package com.cst.intercepterdemo.chain.factory;

import com.cst.intercepterdemo.chain.IIntercepterChain;
import com.cst.intercepterdemo.chain.builder.IChainBuilder;
import com.cst.intercepterdemo.exceptions.IntercepterChainKeyDumplicatedException;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * <ul>
 * <li>文件名称 : com.cst.intercepterdemo.chain.factory.DefaultIntercepterChainFactory
 * </li>
 * <li>版权所有 : 版权所有(C)2016-2020</li>
 * <li>公 司 : CST</li>
 * <li>创建时间 : 2016/12/2</li>
 * <li>修改记录 : </li>
 * </ul>
 * 类说明：拦截器责任链工厂实现
 *
 * @author Allen
 * @version 1.0
 */
public class DefaultIntercepterChainFactory implements  IIntercepterChainFactory,IBuildIntercepterChainFactory {

    private IChainBuilder[] chainBuilders;

    private Map<String,IIntercepterChain> chainCache = new ConcurrentHashMap<>();

    public void setChainBuilders(IChainBuilder[] chainBuilders) {
        this.chainBuilders = chainBuilders;
    }

    @Override
    public IIntercepterChain getChain(String key){
        return chainCache.get(key);
    }

    @Override
    @PostConstruct
    public synchronized void initialChains(){
        chainCache.clear();
        for (IChainBuilder chainBuilder : chainBuilders) {
            List<IIntercepterChain> iIntercepterChains = chainBuilder.buildAll();
            for (IIntercepterChain iIntercepterChain : iIntercepterChains) {
                if(chainCache.containsKey(iIntercepterChain.getChainName())){
                    throw new IntercepterChainKeyDumplicatedException(iIntercepterChain.getChainName());
                }
                chainCache.put(iIntercepterChain.getChainName(),iIntercepterChain);
            }
        }
    }

    @Override
    public synchronized void refreshChain(String key){
        IIntercepterChain chain = null;
        for (IChainBuilder chainBuilder : chainBuilders) {
            IIntercepterChain build = chainBuilder.build(key);
            if(chain!=null && build!=null){
                throw new IntercepterChainKeyDumplicatedException(key);
            }
        }
        if(chain==null){
            chainCache.remove(key);
        }else{
            chainCache.put(key,chain);
        }
    }

}
